Skip to main content

Web Frameworks

Common Components in Rust Web Frameworks

ComponentPurpose
RouterMaps URLs to handler functions
HandlerFunction that processes requests
ExtractorsGet data from URL, query, headers, body
MiddlewareRuns before/after requests
SerializationConverts Rust structs ↔ JSON
Async RuntimeRuns async code (Tokio, async-std)

REST API Using Rocket (Beginner Friendly)

Step 1: Dependencies (Cargo.toml)

[dependencies]
rocket = { version = "0.5.0-rc.3", features = ["json"] }
serde = { version = "1", features = ["derive"] }

Step 2: Code (main.rs)

#[macro_use] extern crate rocket;

use rocket::serde::{Serialize, Deserialize, json::Json};

#[derive(Serialize, Deserialize)]
struct User {
id: u32,
name: String,
}

// GET /user/<id>
#[get("/user/<id>")]
fn get_user(id: u32) -> Json<User> {
Json(User {
id,
name: "Alice".to_string(),
})
}

// POST /user
#[post("/user", format = "json", data = "<user>")]
fn create_user(user: Json<User>) -> Json<User> {
user
}

#[launch]
fn rocket() -> _ {
rocket::build()
.mount("/", routes![get_user, create_user])
}
  • #[get("/user/<id>")]: Defines a GET route with a URL parameter.
  • Json<User>: Automatically serializes/deserializes JSON.
  • #[launch]: Starts the web server.
  • routes![...]: Registers endpoints.

REST API Using Axum (Modern & Scalable)

Dependencies

[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }

Code (main.rs)

use axum::{
routing::{get, post},
Json, Router,
};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;

#[derive(Serialize, Deserialize)]
struct User {
id: u32,
name: String,
}

async fn get_user(axum::extract::Path(id): axum::extract::Path<u32>) -> Json<User> {
Json(User {
id,
name: "Alice".to_string(),
})
}

async fn create_user(Json(user): Json<User>) -> Json<User> {
Json(user)
}

#[tokio::main]
async fn main() {
let app = Router::new()
.route("/user/:id", get(get_user))
.route("/user", post(create_user));

let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
  • Router::new().route(...): Defines routes.
  • Path(id): Extracts route parameters.
  • Json(user): Extracts JSON request body.
  • Uses Tokio runtime for async execution.

REST API Using Actix Web (High Performance)

Dependencies

[dependencies]
actix-web = "4"
serde = { version = "1", features = ["derive"] }

Code (main.rs)

use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct User {
id: u32,
name: String,
}

async fn get_user(path: web::Path<u32>) -> impl Responder {
let user = User {
id: path.into_inner(),
name: "Alice".to_string(),
};
HttpResponse::Ok().json(user)
}

async fn create_user(user: web::Json<User>) -> impl Responder {
HttpResponse::Created().json(user.into_inner())
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/user/{id}", web::get().to(get_user))
.route("/user", web::post().to(create_user))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
  • web::Path<u32> extracts URL parameter.
  • web::Json<User> extracts JSON body.
  • HttpResponse::Ok().json(...) returns JSON.
  • HttpServer::new(...) creates the server.

Summary Comparison

FrameworkEase of UsePerformanceBest Use Case
Rocket⭐⭐⭐⭐⭐⭐⭐⭐⭐Learning, quick apps
Axum⭐⭐⭐⭐⭐⭐⭐⭐⭐Modern async APIs
Actix⭐⭐⭐⭐⭐⭐⭐⭐High-load production
Warp⭐⭐⭐⭐⭐⭐⭐⭐Functional style APIs
Tide⭐⭐⭐⭐⭐⭐⭐⭐Simple services